package com.eelye.util.http.impl;

import com.eelye.util.http.EasyHttpClient;
import com.eelye.util.http.enums.RequestMethodEnum;
import lombok.Getter;
import org.apache.commons.lang3.NotImplementedException;
import org.htmlunit.*;
import org.htmlunit.html.HtmlPage;
import org.htmlunit.javascript.JavaScriptErrorListener;

import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;

/**
 * 模拟浏览器的http client。可以解析html，执行js等，类似于真实的web浏览器，比如chrome。
 */
public class HtmlUnitHttpClient implements EasyHttpClient {

    @Getter
    private WebClient m_webClient = null;

    public HtmlUnitHttpClient() {
        m_webClient = new WebClient(BrowserVersion.CHROME);

        m_webClient.getOptions().setThrowExceptionOnFailingStatusCode(false);
        m_webClient.getOptions().setThrowExceptionOnScriptError(false);
        m_webClient.getOptions().setCssEnabled(false);
        m_webClient.getOptions().setDownloadImages(false);
        m_webClient.getOptions().setDoNotTrackEnabled(true);
        m_webClient.setJavaScriptErrorListener(new JavaScriptErrorListener() {

            @Override
            public void scriptException(HtmlPage htmlPage, ScriptException e) {

            }

            @Override
            public void timeoutError(HtmlPage htmlPage, long l, long l1) {

            }

            @Override
            public void malformedScriptURL(HtmlPage htmlPage, String s, MalformedURLException e) {

            }

            @Override
            public void loadScriptError(HtmlPage htmlPage, URL url, Exception e) {

            }

            @Override
            public void warn(String s, String s1, int i, String s2, int i1) {

            }
        });
    }

    @Override
    public void setProxy(String ip, int port) {
        throw new RuntimeException("未实现");
    }

    @Override
    public <T> T request(RequestMethodEnum method, String uri, String body, Map<String, String> paramHeaders, Class<T> t)
            throws IOException {
        HttpMethod httpMethod = RequestMethodEnum.Get == method ? HttpMethod.GET : HttpMethod.POST;
        WebRequest req = new WebRequest(URI.create(uri).toURL(), httpMethod);
        Map<String, String> headers = new HashMap<>(paramHeaders);
        req.setAdditionalHeaders(headers);
        if (RequestMethodEnum.Post == method) {
            req.setRequestBody(body);
        }
        Page page = m_webClient.getPage(req);

        if (String.class.equals(t)) {
            return (T) page.getWebResponse().getContentAsString();
        }

        return (T) page;
    }

    @Override
    public String getCookie(String key) {
        return m_webClient.getCookieManager().getCookie(key).getValue();
    }

    @Override
    public void close() {
        throw new RuntimeException("未实现");
    }
}
